/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package controladores;

import controladores.exceptions.IllegalOrphanException;
import controladores.exceptions.NonexistentEntityException;
import controladores.exceptions.PreexistingEntityException;
import entidades.Etapa;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import entidades.Informacioncongreso;
import entidades.TipoEtapa;
import entidades.Proyecto;
import entidades.Programacion;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Andres
 */
public class EtapaJpaController {

    public EtapaJpaController() {
        emf = Persistence.createEntityManagerFactory("proyectoCongresoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Etapa etapa) throws PreexistingEntityException, Exception {
        if (etapa.getProgramacionList() == null) {
            etapa.setProgramacionList(new ArrayList<Programacion>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Informacioncongreso informacioncongreso = etapa.getInformacioncongreso();
            if (informacioncongreso != null) {
                informacioncongreso = em.getReference(informacioncongreso.getClass(), informacioncongreso.getCodigoinformacion());
                etapa.setInformacioncongreso(informacioncongreso);
            }
            TipoEtapa tipoEtapa = etapa.getTipoEtapa();
            if (tipoEtapa != null) {
                tipoEtapa = em.getReference(tipoEtapa.getClass(), tipoEtapa.getIdTipoEtapa());
                etapa.setTipoEtapa(tipoEtapa);
            }
            Proyecto proyecto = etapa.getProyecto();
            if (proyecto != null) {
                proyecto = em.getReference(proyecto.getClass(), proyecto.getCodigocongreso());
                etapa.setProyecto(proyecto);
            }
            List<Programacion> attachedProgramacionList = new ArrayList<Programacion>();
            for (Programacion programacionListProgramacionToAttach : etapa.getProgramacionList()) {
                programacionListProgramacionToAttach = em.getReference(programacionListProgramacionToAttach.getClass(), programacionListProgramacionToAttach.getCodigoprogramacion());
                attachedProgramacionList.add(programacionListProgramacionToAttach);
            }
            etapa.setProgramacionList(attachedProgramacionList);
            em.persist(etapa);
            if (informacioncongreso != null) {
                Etapa oldEtapaOfInformacioncongreso = informacioncongreso.getEtapa();
                if (oldEtapaOfInformacioncongreso != null) {
                    oldEtapaOfInformacioncongreso.setInformacioncongreso(null);
                    oldEtapaOfInformacioncongreso = em.merge(oldEtapaOfInformacioncongreso);
                }
                informacioncongreso.setEtapa(etapa);
                informacioncongreso = em.merge(informacioncongreso);
            }
            if (tipoEtapa != null) {
                tipoEtapa.getEtapaList().add(etapa);
                tipoEtapa = em.merge(tipoEtapa);
            }
            if (proyecto != null) {
                proyecto.getEtapaList().add(etapa);
                proyecto = em.merge(proyecto);
            }
            for (Programacion programacionListProgramacion : etapa.getProgramacionList()) {
                Etapa oldEtapaOfProgramacionListProgramacion = programacionListProgramacion.getEtapa();
                programacionListProgramacion.setEtapa(etapa);
                programacionListProgramacion = em.merge(programacionListProgramacion);
                if (oldEtapaOfProgramacionListProgramacion != null) {
                    oldEtapaOfProgramacionListProgramacion.getProgramacionList().remove(programacionListProgramacion);
                    oldEtapaOfProgramacionListProgramacion = em.merge(oldEtapaOfProgramacionListProgramacion);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findEtapa(etapa.getCodigoetapa()) != null) {
                throw new PreexistingEntityException("Etapa " + etapa + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Etapa etapa) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Etapa persistentEtapa = em.find(Etapa.class, etapa.getCodigoetapa());
            Informacioncongreso informacioncongresoOld = persistentEtapa.getInformacioncongreso();
            Informacioncongreso informacioncongresoNew = etapa.getInformacioncongreso();
            TipoEtapa tipoEtapaOld = persistentEtapa.getTipoEtapa();
            TipoEtapa tipoEtapaNew = etapa.getTipoEtapa();
            Proyecto proyectoOld = persistentEtapa.getProyecto();
            Proyecto proyectoNew = etapa.getProyecto();
            List<Programacion> programacionListOld = persistentEtapa.getProgramacionList();
            List<Programacion> programacionListNew = etapa.getProgramacionList();
            List<String> illegalOrphanMessages = null;
            if (informacioncongresoOld != null && !informacioncongresoOld.equals(informacioncongresoNew)) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("You must retain Informacioncongreso " + informacioncongresoOld + " since its etapa field is not nullable.");
            }
            for (Programacion programacionListOldProgramacion : programacionListOld) {
                if (!programacionListNew.contains(programacionListOldProgramacion)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Programacion " + programacionListOldProgramacion + " since its etapa field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (informacioncongresoNew != null) {
                informacioncongresoNew = em.getReference(informacioncongresoNew.getClass(), informacioncongresoNew.getCodigoinformacion());
                etapa.setInformacioncongreso(informacioncongresoNew);
            }
            if (tipoEtapaNew != null) {
                tipoEtapaNew = em.getReference(tipoEtapaNew.getClass(), tipoEtapaNew.getIdTipoEtapa());
                etapa.setTipoEtapa(tipoEtapaNew);
            }
            if (proyectoNew != null) {
                proyectoNew = em.getReference(proyectoNew.getClass(), proyectoNew.getCodigocongreso());
                etapa.setProyecto(proyectoNew);
            }
            List<Programacion> attachedProgramacionListNew = new ArrayList<Programacion>();
            for (Programacion programacionListNewProgramacionToAttach : programacionListNew) {
                programacionListNewProgramacionToAttach = em.getReference(programacionListNewProgramacionToAttach.getClass(), programacionListNewProgramacionToAttach.getCodigoprogramacion());
                attachedProgramacionListNew.add(programacionListNewProgramacionToAttach);
            }
            programacionListNew = attachedProgramacionListNew;
            etapa.setProgramacionList(programacionListNew);
            etapa = em.merge(etapa);
            if (informacioncongresoNew != null && !informacioncongresoNew.equals(informacioncongresoOld)) {
                Etapa oldEtapaOfInformacioncongreso = informacioncongresoNew.getEtapa();
                if (oldEtapaOfInformacioncongreso != null) {
                    oldEtapaOfInformacioncongreso.setInformacioncongreso(null);
                    oldEtapaOfInformacioncongreso = em.merge(oldEtapaOfInformacioncongreso);
                }
                informacioncongresoNew.setEtapa(etapa);
                informacioncongresoNew = em.merge(informacioncongresoNew);
            }
            if (tipoEtapaOld != null && !tipoEtapaOld.equals(tipoEtapaNew)) {
                tipoEtapaOld.getEtapaList().remove(etapa);
                tipoEtapaOld = em.merge(tipoEtapaOld);
            }
            if (tipoEtapaNew != null && !tipoEtapaNew.equals(tipoEtapaOld)) {
                tipoEtapaNew.getEtapaList().add(etapa);
                tipoEtapaNew = em.merge(tipoEtapaNew);
            }
            if (proyectoOld != null && !proyectoOld.equals(proyectoNew)) {
                proyectoOld.getEtapaList().remove(etapa);
                proyectoOld = em.merge(proyectoOld);
            }
            if (proyectoNew != null && !proyectoNew.equals(proyectoOld)) {
                proyectoNew.getEtapaList().add(etapa);
                proyectoNew = em.merge(proyectoNew);
            }
            for (Programacion programacionListNewProgramacion : programacionListNew) {
                if (!programacionListOld.contains(programacionListNewProgramacion)) {
                    Etapa oldEtapaOfProgramacionListNewProgramacion = programacionListNewProgramacion.getEtapa();
                    programacionListNewProgramacion.setEtapa(etapa);
                    programacionListNewProgramacion = em.merge(programacionListNewProgramacion);
                    if (oldEtapaOfProgramacionListNewProgramacion != null && !oldEtapaOfProgramacionListNewProgramacion.equals(etapa)) {
                        oldEtapaOfProgramacionListNewProgramacion.getProgramacionList().remove(programacionListNewProgramacion);
                        oldEtapaOfProgramacionListNewProgramacion = em.merge(oldEtapaOfProgramacionListNewProgramacion);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = etapa.getCodigoetapa();
                if (findEtapa(id) == null) {
                    throw new NonexistentEntityException("The etapa with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Etapa etapa;
            try {
                etapa = em.getReference(Etapa.class, id);
                etapa.getCodigoetapa();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The etapa with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Informacioncongreso informacioncongresoOrphanCheck = etapa.getInformacioncongreso();
            if (informacioncongresoOrphanCheck != null) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Etapa (" + etapa + ") cannot be destroyed since the Informacioncongreso " + informacioncongresoOrphanCheck + " in its informacioncongreso field has a non-nullable etapa field.");
            }
            List<Programacion> programacionListOrphanCheck = etapa.getProgramacionList();
            for (Programacion programacionListOrphanCheckProgramacion : programacionListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Etapa (" + etapa + ") cannot be destroyed since the Programacion " + programacionListOrphanCheckProgramacion + " in its programacionList field has a non-nullable etapa field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            TipoEtapa tipoEtapa = etapa.getTipoEtapa();
            if (tipoEtapa != null) {
                tipoEtapa.getEtapaList().remove(etapa);
                tipoEtapa = em.merge(tipoEtapa);
            }
            Proyecto proyecto = etapa.getProyecto();
            if (proyecto != null) {
                proyecto.getEtapaList().remove(etapa);
                proyecto = em.merge(proyecto);
            }
            em.remove(etapa);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Etapa> findEtapaEntities() {
        return findEtapaEntities(true, -1, -1);
    }

    public List<Etapa> findEtapaEntities(int maxResults, int firstResult) {
        return findEtapaEntities(false, maxResults, firstResult);
    }

    private List<Etapa> findEtapaEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Etapa.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Etapa findEtapa(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Etapa.class, id);
        } finally {
            em.close();
        }
    }

    public int getEtapaCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Etapa> rt = cq.from(Etapa.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }

}
